import sys
import clr

sys.path.append(r"C:\Program Files (x86)\IronPython 2.7\Lib")
sys.path.append(r"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client")

clr.AddReferenceToFile("UIAutomationClient.dll")
clr.AddReferenceToFile("UIAutomationTypes.dll")

from SimpleXMLRPCServer import SimpleXMLRPCServer as Server
from System.Windows.Automation import *


def _find_first(condition):
    desktop = AutomationElement.RootElement
    condition_tree = condition.split('/')
    control = []
    for i, sub_tree in enumerate(condition_tree):
        print "Level: %d" % i
        condition_leaves = sub_tree.split('&')
        property_condition = {}
        automation_property = {}
        for j, condition_leaf in enumerate(condition_leaves):
            print "Condition: %d %s" % (j, condition_leaf)
            sub_leaf = condition_leaf.split(':')
            automation_property[j] = "AutomationElement.%sProperty" % sub_leaf[0]
            control_type = "ControlType." + sub_leaf[1]
            if sub_leaf[0] == "ControlType":
                property_condition[j] = PropertyCondition(eval(automation_property[j]), eval(control_type))
            else:
                property_condition[j] = PropertyCondition(eval(automation_property[j]), sub_leaf[1])
        if len(condition_leaves) == 1:
            tmp_condition = property_condition[0]
        else:
            tmp_condition = AndCondition(property_condition)
        if i == 0:
            print "Parent: %s %s" % (desktop.Current.Name, desktop.Current.LocalizedControlType)
            control.append(desktop.FindFirst(TreeScope.Children, tmp_condition))
        elif control[i-1] is not None:
            print "Self: %s %s" % (control[i-1].Current.Name, control[i-1].Current.LocalizedControlType)
            control.append(control[i-1].FindFirst(TreeScope.Children, tmp_condition))
        if control[i] is None:
            print "Self: can not find."
    final_result = control[-1]
    return final_result

# def action_range_value():
#    pass


def action_value(condition, s):
    try:
        auto_element = _find_first(condition)
        value_pattern = auto_element.GetCurrentPattern(ValuePattern.Pattern)
        value_pattern.SetValue(s)
        return 0
    except:
        return "Error..."


def action_invoke(condition):
    # click
    try:
        auto_element = _find_first(condition)
        invoke_pattern = auto_element.GetCurrentPattern(InvokePattern.Pattern)
        invoke_pattern.Invoke()
        return 0
    except:
        return "Error..."

# def action_scroll():
#    pass

# def action_set_scroll_percent():
#    pass


def action_expand_collapse(condition, opt):
    try:
        auto_element = _find_first(condition)
        expand_collapse_pattern = auto_element.GetCurrentPattern(ExpandCollapsePattern.Pattern)
        if opt == "Expand":
            expand_collapse_pattern.Expand()
        elif opt == "Collapse":
            expand_collapse_pattern.Collapse()
        return 0
    except:
        return "Error..."


def action_window_close(condition):
    try:
        auto_element = _find_first(condition)
        window_pattern = auto_element.GetCurrentPattern(WindowPattern.Pattern)
        window_pattern.Close()
        return 0
    except:
        return "Error..."


def action_set_window_visual_state(condition, opt):
    window_visual_state = WindowVisualState.Normal
    try:
        auto_element = _find_first(condition)
        if opt == "Normal":
            window_visual_state = WindowVisualState.Normal
        elif opt == "Maximized":
            window_visual_state = WindowVisualState.Maximized
        elif opt == "Minimized":
            window_visual_state = WindowVisualState.Minimized
        window_pattern = auto_element.GetCurrentPattern(WindowPattern.Pattern)
        window_pattern.SetWindowVisualState(window_visual_state)
        return 0
    except:
        return "Error..."


def action_selection_item(condition, opt):
    # Radio
    try:
        auto_element = _find_first(condition)
        selection_item_pattern_pattern = auto_element.GetCurrentPattern(SelectionItemPattern.Pattern)
        if opt == "AddToSelection":
            selection_item_pattern_pattern.AddToSelection()
        elif opt == "RemoveFromSelection":
            selection_item_pattern_pattern.RemoveFromSelection()
        elif opt == "Select":
            selection_item_pattern_pattern.Select()
        return 0
    except:
        return "Error..."

# def action_dock():
#    pass


def action_toggle(condition):
    # checkbox
    try:
        auto_element = _find_first(condition)
        toggle_pattern = auto_element.GetCurrentPattern(TogglePattern.Pattern)
        toggle_pattern.Toggle()
        return 0
    except:
        return "Error..."

# def action_transform_move():
#    pass

# def action_transform_resize():
#    pass

# def action_transform_rotate():
#    pass

# def action_scroll_item():
#    pass


def action_control_exists(condition):
    try:
        auto_element = _find_first(condition)
        if auto_element is not None:
            return 0
    except:
        return "Error..."


def action_set_focus(condition):
    try:
        auto_element = _find_first(condition)
        auto_element.SetFocus()
        return 0
    except:
        return "Error..."

# def action_walk_control_elements():
#    pass


def action_grid_get_item_name(condition, row, column):
    try:
        auto_element = _find_first(condition)
        grid_pattern = auto_element.GetCurrentPattern(GridPattern.Pattern)
        grid_item = grid_pattern.GetItem(row, column)
        item_name = grid_item.Current.Name
        return item_name
    except:
        return "Error..."


def action_multiple_view(condition, view_id, opt):
    try:
        auto_element = _find_first(condition)
        multiple_view_pattern = auto_element.GetCurrentPattern(MultipleViewPattern.Pattern)
        if opt == "GetViewName":
            result = multiple_view_pattern.GetViewName(view_id)
        elif opt == "SetCurrentView":
            multiple_view_pattern.SetCurrentView(view_id)
            result = "1"
        else:
            result = 0
        return result
    except:
        return "Error..."


def action_shortcut(condition, img_path):
    try:
        auto_element = _find_first(condition)
        UIAutomationClass.shortcut(auto_element, img_path)
        return 0
    except:
        return "Error..."


def action_get_property(condition, opt="Name"):
    # property
    try:
        auto_element = _find_first(condition)
        if opt == "Name":
            return auto_element.Current.Name
        else:
            return "KeyError."
    except:
        return "Error..."

srv = Server(("127.0.0.1", 1337))
if not srv:
    exit(1)
srv.register_introspection_functions()
# srv.register_function(action_click)
# srv.register_function(action_range_value)
srv.register_function(action_value)
srv.register_function(action_invoke)
# srv.register_function(action_scroll)
# srv.register_function(action_set_scroll_percent)
srv.register_function(action_expand_collapse)
srv.register_function(action_window_close)
srv.register_function(action_set_window_visual_state)
srv.register_function(action_selection_item)
srv.register_function(action_toggle)
# srv.register_function(action_transform_move)
# srv.register_function(action_transform_resize)
# srv.register_function(action_transform_rotate)
# srv.register_function(action_scroll_item)
srv.register_function(action_control_exists)
srv.register_function(action_set_focus)
# srv.register_function(action_walk_control_elements)
srv.register_function(action_grid_get_item_name)
srv.register_function(action_multiple_view)
srv.register_function(action_shortcut)
srv.register_function(action_get_property)
srv.serve_forever()
